﻿using System;
using System.Collections.Generic;
using System.Data;
using l1cs.server.templates;
using MySql.Data.MySqlClient;
using l1cs.server.model.Instance;
using l1cs.server.model;
using l1cs.server.utils;

namespace l1cs.server.datatables
{
    class SkillsTable
    {
        private static Logger _log = Logger.getLogger( typeof( SkillsTable ).FullName );

        private static SkillsTable _instance;

        private Dictionary<int, L1Skills> _skills = new Dictionary<int, L1Skills>();

        public static SkillsTable getInstance()
        {
            if ( _instance == null )
            {
                _instance = new SkillsTable();
            }
            return _instance;
        }

        private SkillsTable()
        {/*TTOK*/
            String sqlstr = "SELECT * FROM skills";
            using ( MySqlWrapper wrapper = new MySqlWrapper() )
            {
                foreach ( DataRow item in wrapper.GetDataTable( sqlstr ).Rows )
                {
                    L1Skills l1skills = new L1Skills();
                    int skill_id = SqlUtils.toInt( item["skill_id"] );
                    l1skills.setSkillId( skill_id );
                    l1skills.setName( Convert.ToString( item["name"] ) );
                    l1skills.setSkillLevel( SqlUtils.toInt( item["skill_level"] ) );
                    l1skills.setSkillNumber( SqlUtils.toInt( item["skill_number"] ) );
                    l1skills.setMpConsume( SqlUtils.toInt( item["mpConsume"] ) );
                    l1skills.setHpConsume( SqlUtils.toInt( item["hpConsume"] ) );
                    l1skills.setItemConsumeId( SqlUtils.toInt( item["itemConsumeId"] ) );
                    l1skills.setItemConsumeCount( SqlUtils.toInt( item["itemConsumeCount"] ) );
                    l1skills.setReuseDelay( SqlUtils.toInt( item["reuseDelay"] ) );
                    l1skills.setBuffDuration( SqlUtils.toInt( item["buffDuration"] ) );
                    l1skills.setTarget( Convert.ToString( item["target"] ) );
                    l1skills.setTargetTo( SqlUtils.toInt( item["target_to"] ) );
                    l1skills.setDamageValue( SqlUtils.toInt( item["damage_value"] ) );
                    l1skills.setDamageDice( SqlUtils.toInt( item["damage_dice"] ) );
                    l1skills.setDamageDiceCount( SqlUtils.toInt( item["damage_dice_count"] ) );
                    l1skills.setProbabilityValue( SqlUtils.toInt( item["probability_value"] ) );
                    l1skills.setProbabilityDice( SqlUtils.toInt( item["probability_dice"] ) );
                    l1skills.setAttr( SqlUtils.toInt( item["attr"] ) );
                    l1skills.setType( SqlUtils.toInt( item["type"] ) );
                    l1skills.setLawful( SqlUtils.toInt( item["lawful"] ) );
                    l1skills.setRanged( SqlUtils.toInt( item["ranged"] ) );
                    l1skills.setArea( SqlUtils.toInt( item["area"] ) );
                    l1skills.setThrough( Convert.ToBoolean( item["through"] ) );
                    l1skills.setId( SqlUtils.toInt( item["id"] ) );
                    l1skills.setNameId( Convert.ToString( item["nameid"] ) );
                    l1skills.setActionId( SqlUtils.toInt( item["action_id"] ) );
                    l1skills.setCastGfx( SqlUtils.toInt( item["castgfx"] ) );
                    l1skills.setCastGfx2( SqlUtils.toInt( item["castgfx2"] ) );
                    l1skills.setSysmsgIdHappen( SqlUtils.toInt( item["sysmsgID_happen"] ) );
                    l1skills.setSysmsgIdStop( SqlUtils.toInt( item["sysmsgID_stop"] ) );
                    l1skills.setSysmsgIdFail( SqlUtils.toInt( item["sysmsgID_fail"] ) );

                    _skills[skill_id] = l1skills;
                }
            }
            _log.config( "スキル " + _skills.Count + "件ロード" );
        }

        /// <summary>
        /// プレイヤーにスペルを保存する。
        /// </summary>
        /// <param name="playerobjid"></param>
        /// <param name="skillid"></param>
        /// <param name="skillname"></param>
        /// <param name="active"></param>
        /// <param name="time"></param>
        public void spellMastery( int playerobjid, int skillid, String skillname, int active, int time )
        {/*TTOK*/
            if ( spellCheck( playerobjid, skillid ) )
            {
                return;
            }
            L1PcInstance pc = (L1PcInstance)L1World.getInstance().findObject( playerobjid );
            if ( pc != null )
            {
                pc.setSkillMastery( skillid );
            }

            String sqlstr = @"INSERT INTO character_skills SET 
                                char_obj_id    = ?1, 
                                skill_id       = ?2, 
                                skill_name     = ?3, 
                                is_active      = ?4, 
                                activetimeleft = ?5";
            using ( MySqlWrapper wrapper = new MySqlWrapper() )
            {
                MySqlCommand cmd = new MySqlCommand( sqlstr );
                cmd.Parameters.Add( new MySqlParameter( "?1", playerobjid ) );
                cmd.Parameters.Add( new MySqlParameter( "?2", skillid ) );
                cmd.Parameters.Add( new MySqlParameter( "?3", skillname ) );
                cmd.Parameters.Add( new MySqlParameter( "?4", active ) );
                cmd.Parameters.Add( new MySqlParameter( "?5", time ) );
                wrapper.ExecNonQuery( cmd );
            }
        }

        /// <summary>
        /// プレイヤーからスペルを削除する。
        /// </summary>
        /// <param name="playerobjid"></param>
        /// <param name="skillid"></param>
        public void spellLost( int playerobjid, int skillid )
        {/*TTOK*/
            L1PcInstance pc = (L1PcInstance)L1World.getInstance().findObject( playerobjid );
            if ( pc != null )
            {
                pc.removeSkillMastery( skillid );
            }

            String sqlstr = @"DELETE FROM character_skills  WHERE
                                char_obj_id = ?1 AND skill_id    = ?2";
            using ( MySqlWrapper wrapper = new MySqlWrapper() )
            {
                MySqlCommand cmd = new MySqlCommand( sqlstr );
                cmd.Parameters.Add( "?1", MySqlDbType.Int32 ).Value = playerobjid;
                cmd.Parameters.Add( "?2", MySqlDbType.Int32 ).Value = skillid;
                wrapper.ExecNonQuery( cmd );
            }
        }

        /// <summary>
        /// プレイヤーがスペルを覚えいるか返す。
        /// </summary>
        /// <param name="playerobjid"></param>
        /// <param name="skillid"></param>
        /// <returns></returns>
        public bool spellCheck( int playerobjid, int skillid )
        {/*TTOK*/
            bool ret = false;
            String sqlstr = @"SELECT * FROM character_skills WHERE 
                                char_obj_id=?1 AND skill_id=?2";
            using ( MySqlWrapper wrapper = new MySqlWrapper() )
            {
                MySqlCommand cmd = new MySqlCommand( sqlstr );
                cmd.Parameters.Add( new MySqlParameter( "?1", playerobjid ) );
                cmd.Parameters.Add( new MySqlParameter( "?2", skillid ) );
                DataTable dt = wrapper.GetDataTable( cmd );
                foreach ( DataRow item in dt.Rows )
                {
                    ret = true;
                }
            }
            return ret;
        }

        public L1Skills getTemplate( int i )
        {/*TTOK*/
            L1Skills ret;
            _skills.TryGetValue( i, out ret );
            return ret;
        }
    }
}
